#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <string.h>

#include <stdint.h>

#include "sys_gpio.hpp"

#define TCK_GP 60
#define TDO_GP 61
#define TMS_GP 62
#define TDI_GP 63
#define TCK_S "60"
#define TDO_S "61"
#define TMS_S "62"
#define TDI_S "63"
#define TCK_Str C(60)
#define TDO_Str C(61)
#define TMS_Str C(62)
#define TDI_Str C(63)
#define C(x) "gpio"#x"/"

#define ROOT_PATH "/sys/class/gpio/"
#define VALUE "value"
#define DIRECTION "direction"
#define EXPORT_PATH ROOT_PATH "export"
#define UNEXPORT_PATH ROOT_PATH "unexport"

int fd_export = 0;
int fd_unexport = 0;
int fd_dev[4] = { 0 };
int fd_dir[4] = { 0 };
int ret;
char buf[10]={0};
int i=0;

int mt76x8_gpio_get_pin(int pin)
{
	memset(buf,0,sizeof(buf));
	// printf("%d ",pin);
	// //strcpy(buf, "");

	
	// for(i=0;i<50;i++)
	// {
	// 	printf("%cQ",buf[i]);
	// }
	fd_dev[1] = open(ROOT_PATH TDO_Str VALUE, O_RDWR);
	if (fd_dev[1] < 0) { printf("open dev1 fail!\n"); return -1; }

	ret=read(fd_dev[pin - 60], buf, sizeof(buf));
//	printf("opcode_read action:%s", buf);//自带换行
	close(fd_dev[1]);
	// printf("%s\n", buf);
	
	// for(i=0;i<50;i++)
	// {
	// 	printf("%cQ",buf[i]);
	// }
	// printf("\n");
	if (ret < 0)
	{
		printf("read error!\n");
		sys_gpio_stop();
		return 0;//test
	}

	if (strcmp(buf, "0\n") == 0)
	{
		// printf("read: 0\n");
		return 0;
	}
	else
	{
		// printf("read: 1\n");
		return 1;
	}
}

void mt76x8_gpio_set_pin_direction(int pin, int is_output)
{
	if (is_output)
	{
		strcpy(buf, "out");
	}
	else
	{
		strcpy(buf, "in");
	}
	// printf("write dir\n");
	ret = write(fd_dir[pin - 60], buf, strlen(buf));
	// printf("%s\n", buf);
	if (ret < 0)
	{
		printf("write dir error!\n");
		sys_gpio_stop();
		return ;
	}
}

void mt76x8_gpio_set_pin_value(int pin, int value)
{
	if (value)
	{
		strcpy(buf, "1");
	}
	else
	{
		strcpy(buf, "0");
	}
	// printf("write val\n");
	ret = write(fd_dev[pin - 60], buf, strlen(buf));
	// switch(pin)
	// {
	// 	case TCK_GP:printf("opcode_tck ");break;
	// 	case TDO_GP:printf("opcode_tdo ");break;
	// 	case TMS_GP:printf("opcode_tms ");break;
	// 	case TDI_GP:printf("opcode_tdi ");break;
	// }
	// printf("write:%d\n",value);
	// printf("%s\n", buf);
	if (ret < 0)
	{
		printf("write val error!\n");
		sys_gpio_stop();
		return;
	}

}

int sys_gpio_start(void)
{
	printf("gpio start!\n");
	return 0;
}
int sys_gpio_stop(void)
{
	printf("begin stop!\n");
	fd_unexport=open(UNEXPORT_PATH, O_WRONLY);
	if(fd_unexport<0)
	{
		printf("open unexport error!\n");
	}
	else
	{
		strcpy(buf,TMS_S);
		printf("%s\n",buf);
		ret=write(fd_unexport, buf, strlen(buf));
		if(ret<0){printf("write TMS error!\n");return -1;}
		strcpy(buf,TCK_S);
		printf("%s\n",buf);
		ret=write(fd_unexport, buf, strlen(buf));
		if(ret<0){printf("write TCK error!\n");return -1;}
		strcpy(buf,TDI_S);
		printf("%s\n",buf);
		ret=write(fd_unexport, buf, strlen(buf));
		if(ret<0){printf("write TDI error!\n");return -1;}
		strcpy(buf,TDO_S);
		printf("%s\n",buf);
		ret=write(fd_unexport, buf, strlen(buf));
		if(ret<0){printf("write TDO error!\n");return -1;}
		printf("unexport successed!\n");
	}

	close(fd_export);
	for(i=0;i<4;i++)
		close(fd_dir[i]);
	for (i = 0; i < 4; i++)
		close(fd_dev[i]);
	close(fd_unexport);
	printf("stop!\n");
	return 0;
}
int sys_gpio_init(void)
{

	printf("%s\n", EXPORT_PATH);
	printf("%s\n", ROOT_PATH TMS_Str DIRECTION);
	printf("%s\n", ROOT_PATH TMS_Str VALUE);
	fd_export = open(EXPORT_PATH, O_WRONLY);
	if (fd_export < 0) { printf("open export fail!\n"); return -1; }

	strcpy(buf,TMS_S);
	printf("%s\n",buf);
	ret=write(fd_export, buf, strlen(buf));
	if(ret<0){printf("write TMS error!\n");return -1;}
	strcpy(buf,TCK_S);
	printf("%s\n",buf);
	ret=write(fd_export, buf, strlen(buf));
	if(ret<0){printf("write TCK error!\n");return -1;}
	strcpy(buf,TDI_S);
	printf("%s\n",buf);
	ret=write(fd_export, buf, strlen(buf));
	if(ret<0){printf("write TDI error!\n");return -1;}
	strcpy(buf,TDO_S);
	printf("%s\n",buf);
	ret=write(fd_export, buf, strlen(buf));
	if(ret<0){printf("write TDO error!\n");return -1;}


	fd_dir[2] = open(ROOT_PATH TMS_Str DIRECTION, O_RDWR);
	if (fd_dir[2] < 0) { printf("open dir2 fail!\n"); return -1; }
	fd_dev[2] = open(ROOT_PATH TMS_Str VALUE, O_RDWR);
	if (fd_dev[2] < 0) { printf("open dev2 fail!\n"); return -1; }
	printf("fd_dir2:%d fd_dev2:%d\n",fd_dir[2],fd_dev[2]);

	fd_dir[0] = open(ROOT_PATH TCK_Str DIRECTION, O_RDWR);
	if (fd_dir[0] < 0) { printf("open dir0 fail!\n"); return -1; }
	fd_dev[0] = open(ROOT_PATH TCK_Str VALUE, O_RDWR);
	if (fd_dev[0] < 0) { printf("open dev0 fail!\n"); return -1; }
	printf("fd_dir0:%d fd_dev0:%d\n",fd_dir[0],fd_dev[0]);

	fd_dir[3] = open(ROOT_PATH TDI_Str DIRECTION, O_RDWR);
	if (fd_dir[3] < 0) { printf("open dir3 fail!\n"); return -1; }
	fd_dev[3] = open(ROOT_PATH TDI_Str VALUE, O_RDWR);
	if (fd_dev[3] < 0) { printf("open dev3 fail!\n"); return -1; }
	printf("fd_dir3:%d fd_dev3:%d\n",fd_dir[3],fd_dev[3]);

	fd_dir[1] = open(ROOT_PATH TDO_Str DIRECTION, O_RDWR);
	if (fd_dir[1] < 0) { printf("open dir1 fail!\n"); return -1; }
	// fd_dev[1] = open(ROOT_PATH TDO_Str VALUE, O_RDWR);
	// if (fd_dev[1] < 0) { printf("open dev1 fail!\n"); return -1; }
	printf("fd_dir1:%d fd_dev1:%d\n",fd_dir[1],fd_dev[1]);


//	mt76x8_gpio_set_pin_direction(53, 1);
//	mt76x8_gpio_set_pin_value(53, 0);

	//tdi out//CLK//9
	mt76x8_gpio_set_pin_direction(TDI_GP, 1);
	mt76x8_gpio_set_pin_value(TDI_GP, 0);

	//tms out//DI//5
	mt76x8_gpio_set_pin_direction(TMS_GP, 1);
	mt76x8_gpio_set_pin_value(TMS_GP, 0);

	//tck out//DO//1
	mt76x8_gpio_set_pin_direction(TCK_GP, 1);
	mt76x8_gpio_set_pin_value(TCK_GP, 0);

	//tdo in//WS//3
	mt76x8_gpio_set_pin_direction(TDO_GP, 0);
	//GND//10
	printf("init ok!\n");
	return 0;

}


/* 
int main()
{
	sys_gpio_init();
	sys_gpio_start();
	while (1)
	{
		// int a,b,c;
		// printf(">");
		// scanf("%d%d%d", &a,&b,&c);
		// if (a != 60&&a!=61&&a!=62&&a!=63)break;
		// if(b)
		// 	mt76x8_gpio_set_pin_value(a, c);
		// else
		// {
		// 	mt76x8_gpio_set_pin_direction(a,c);
		// }
		


		//mt76x8_gpio_get_pin(61);
	}
	sys_gpio_stop();
	return 0;
}
*/